/*MyPhotoIndex Free Photo Organizer <www.myphotoindex.com>
  Copyright (C) <2006-2009>  <Asaf Yarkoni asaf@yarkoni.net>

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.*/
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Drawing;
using MyPhotoIndex.Interfaces;
using System.IO;
using System.Windows.Forms.Design;
using System.Drawing.Design;
using System.Globalization;
using System.Threading;
using System.Collections.ObjectModel;
using MyPhotoIndex.ImageBank;
using MyPhotoIndex.Utilities;
using MyPhotoIndex.Controls;

namespace MyPhotoIndex.Settings
{
    [Serializable]
    public class ApplicationSettings : IDynamicSetting
    {
        public event EventHandler SettingsSaved;

        private String m_configVersion;
        private String m_indexDb;
        private String m_defaultImagesPath;
        private String m_lastCameraImport;
        private String m_defaultLanguage;
        [NonSerialized]
        private CultureInfo m_defaultSystemCulture;
        private int m_spliter1Distance;
        private int m_spliter2Distance;
        private int m_spliter3Distance;
        private int m_thumbnailsize;
        private String m_defaultMailPlugin;
        private String m_defaultPrintPlugin;
        private Size m_defaultMailImageSize;
        private int m_savedScreenResolutionW;
        private int m_savedScreenResolutionH;
        private bool m_deleteImagesAfterTransfer;
        private int m_slideShowTransitionInterval;
        private String m_defaultImagesEditSoftware;
        private bool m_firstRun;
        private int m_lastFilterTreeView;
        private bool m_showShareSettings;
        private String m_lastImageSorting;
        private bool m_sortDescending;
        private bool m_sendToRecycleBin;
        private bool m_usePrintPreviewInsteadOfPrinter;
        private List<SavedQuery> m_savedQueries;
        private String m_versionCheckUrl;
        private String m_versionDownloadUrl;
        private bool m_automaticallyCheckForVersions;
        private string m_installationId;
        private String m_defaultSlideShowEffectPlugin;
        private bool m_showTagSortMessage;
        private bool m_showTagParentChangeMessage;
        private Size m_cachedThumbnailSize;
        private bool m_filterSyncronizedSelection;
        private string m_imageCachePath;
        private bool m_updateImageMetadataOnChange;
        private bool m_showImageCreateVersionOnEditMessage;
        private string m_displayDateFormat;
        private string m_lastMoveToPath;
        private string m_lastImportPath;
        private ProxySettings m_proxySettings;
        private RecentlyUsedIndexList m_recentlyUsedIndexes;
        private KeyboardMappings m_keyboardMappings;
        private ThumbnailTextInfo m_thumbnailTextInfoDisplayType;

        public ApplicationSettings()
        {
            m_configVersion = "1.24";
            m_defaultLanguage = GetDefaultLocale();
            m_displayDateFormat = CultureInfo.CurrentUICulture.DateTimeFormat.ShortDatePattern;
            m_spliter1Distance = 255;// 1020;
            m_spliter2Distance = 380;
            m_spliter3Distance = 290;
            m_thumbnailsize = 4;
            m_defaultMailImageSize = new Size(1024, 768);
            m_savedScreenResolutionW = 1024;
            m_savedScreenResolutionH = 715;
            m_deleteImagesAfterTransfer = true;
            m_slideShowTransitionInterval = 2;
            m_firstRun = true;
            m_showShareSettings = true;
            m_sendToRecycleBin = true;
            m_versionCheckUrl = String.Empty;
            m_versionDownloadUrl = String.Empty;
            m_automaticallyCheckForVersions = true;
            m_savedQueries = new List<SavedQuery>();
            m_installationId = Guid.NewGuid().ToString();
            m_showTagSortMessage = true;
            m_showTagParentChangeMessage = true;
            m_cachedThumbnailSize = new Size(320, 240);
            m_showImageCreateVersionOnEditMessage = true;
            m_proxySettings = new ProxySettings();
            m_recentlyUsedIndexes = new RecentlyUsedIndexList();
            m_keyboardMappings = new KeyboardMappings();
            m_thumbnailTextInfoDisplayType = ThumbnailTextInfo.DateTaken;
        }

        private string GetDefaultLocale()
        {
            try
            {
                m_defaultSystemCulture = Thread.CurrentThread.CurrentUICulture;
                if (string.Compare(m_defaultSystemCulture.Name, "en-US") != 0 &&
                   string.Compare(m_defaultSystemCulture.Name, "he-IL") != 0 &&
                   string.Compare(m_defaultSystemCulture.Name, "lt-LT") != 0)
                {
                    return "en-US";
                }

                return m_defaultSystemCulture.Name;
            }
            catch { }

            return "en-US";
        }

        public override String ToString()
        {
            return "General Settings";
        }

        public static ApplicationSettings Default
        {
            get
            {
                return (ApplicationSettings)DynamicConfiguration.Default[typeof(ApplicationSettings)];
            }
        }

        public void Save()
        {
            DynamicConfiguration.Default.Save();

            if (SettingsSaved != null)
            {
                SettingsSaved.Invoke(this, EventArgs.Empty);
            }
        }

        [Browsable(false)]
        public String ProductId
        {
            get { return "3422448C-0143-408e-9A3F-D681999F4F1A"; }
        }

        [Browsable(false)]
        public string InstallationId
        {
            get { return m_installationId; }
            set { m_installationId = value; }
        }

        [Browsable(false)]
        public String ConfigVersion
        {
            get { return m_configVersion; }
            set { m_configVersion = value; }
        }

        [Browsable(false)]
        public String IndexDb
        {
            get { return m_indexDb; }
            set { m_indexDb = value; }
        }

        [Browsable(false)]
        public String DefaultImagesPath
        {
            get { return m_defaultImagesPath; }
            set { m_defaultImagesPath = value; }
        }

        [Browsable(false)]
        public String DefaultLanguage
        {
            get { return m_defaultLanguage; }
            set { m_defaultLanguage = value; }
        }

        //[Browsable(false)]
        //public CultureInfo DefaultSystemCulture
        //{
        //    get { return m_defaultSystemCulture; }
        //    set { m_defaultSystemCulture = value; }
        //}

        [Browsable(false)]
        public int Splitter1Distance
        {
            get { return m_spliter1Distance; }
            set { m_spliter1Distance = value; }
        }

        [Browsable(false)]
        public int Splitter2Distance
        {
            get { return m_spliter2Distance; }
            set { m_spliter2Distance = value; }
        }

        [Browsable(false)]
        public int Splitter3Distance
        {
            get { return m_spliter3Distance; }
            set { m_spliter3Distance = value; }
        }

        [Browsable(false)]
        public int Thumbnailsize
        {
            get { return m_thumbnailsize; }
            set { m_thumbnailsize = value; }
        }

        [Browsable(false)]
        public String DefaultMailPlugin
        {
            get { return m_defaultMailPlugin; }
            set { m_defaultMailPlugin = value; }
        }

        [Browsable(false)]
        public String DefaultPrintPlugin
        {
            get { return m_defaultPrintPlugin; }
            set { m_defaultPrintPlugin = value; }
        }

        [Browsable(false)]
        public Size DefaultMailImageSize
        {
            get { return m_defaultMailImageSize; }
            set { m_defaultMailImageSize = value; }
        }

        [Browsable(false)]
        public int SavedScreenWidthResolution
        {
            get { return m_savedScreenResolutionW; }
            set { m_savedScreenResolutionW = value; }
        }

        [Browsable(false)]
        public int SavedScreenHeightResolution
        {
            get { return m_savedScreenResolutionH; }
            set { m_savedScreenResolutionH = value; }
        }

        [Category("Image Transfer")]
        [DisplayName("Delete images after successful transfer")]
        public bool DeleteImagesAfterTransfer
        {
            get { return m_deleteImagesAfterTransfer; }
            set { m_deleteImagesAfterTransfer = value; }
        }

        [Category("Full Screen Display")]
        [DisplayName("Slide show interval (seconds)")]
        [DefaultValue(2)]
        public int SlideShowTransitionInterval
        {
            get { return m_slideShowTransitionInterval; }
            set { m_slideShowTransitionInterval = value; }
        }

        [Category("Image Editing")]
        [DisplayName("Default image editing software")]
        [EditorAttribute(typeof(UIFileNameEditor), typeof(UITypeEditor))]
        public String DefaultImagesEditSoftware
        {
            get { return m_defaultImagesEditSoftware; }
            set { m_defaultImagesEditSoftware = value; }
        }

        [Browsable(false)]
        public bool FirstRun
        {
            get { return m_firstRun; }
            set { m_firstRun = value; }
        }

        [Browsable(false)]
        public String LastCameraImport
        {
            get { return m_lastCameraImport; }
            set { m_lastCameraImport = value; }
        }

        [Browsable(false)]
        public String LastImageSorting
        {
            get { return m_lastImageSorting; }
            set { m_lastImageSorting = value; }
        }

        [Browsable(false)]
        public bool SortDescending
        {
            get { return m_sortDescending; }
            set { m_sortDescending = value; }
        }

        [Browsable(false)]
        public int LastFilterTreeView
        {
            get { return m_lastFilterTreeView; }
            set { m_lastFilterTreeView = value; }
        }

        [Category("Image Sharing")]
        [DisplayName("Show image sharing settings")]
        public bool ShowShareSettingsForm
        {
            get { return m_showShareSettings; }
            set { m_showShareSettings = value; }
        }

        [Browsable(false)]
        [Category("File Operations")]
        [DisplayName("Use Recycle Bin")]
        [Description("When Deleting files from Disk, move them to Windows Recycle Bin(local files only)")]
        public bool SendToRecycleBin
        {
            get { return m_sendToRecycleBin; }
            set { m_sendToRecycleBin = value; }
        }

        [Browsable(false)]
        public bool UsePrintPreviewInsteadOfPrinter
        {
            get { return m_usePrintPreviewInsteadOfPrinter; }
            set { m_usePrintPreviewInsteadOfPrinter = value; }
        }

        [Browsable(false)]
        public List<SavedQuery> SavedQueries
        {
            get { return m_savedQueries; }
            set { m_savedQueries = value; }
        }

        [Browsable(false)]
        public String VersionCheckUrl
        {
            get { return m_versionCheckUrl; }
            set { m_versionCheckUrl = value; }
        }

        [Browsable(false)]
        public String VersionDownloadUrl
        {
            get { return m_versionDownloadUrl; }
            set { m_versionDownloadUrl = value; }
        }

        [Category("Version updates")]
        [DisplayName("Check for updates on application startup")]
        [Description("Check the web for new MyPhotoIndex versions")]
        public bool CheckForUpdatesOnStartup
        {
            get { return m_automaticallyCheckForVersions; }
            set { m_automaticallyCheckForVersions = value; }
        }

        [Browsable(false)]
        public String DefaultSlideShowEffectPlugin
        {
            get { return m_defaultSlideShowEffectPlugin; }
            set { m_defaultSlideShowEffectPlugin = value; }
        }

        [Category("Warnings")]
        [DisplayName("Ask before sorting tags")]
        [Description("Show a warning message before sorting tags")]
        public bool ShowTagSortMessage
        {
            get { return m_showTagSortMessage; }
            set { m_showTagSortMessage = value; }
        }

        [Category("Warnings")]
        [DisplayName("Ask before moving tags")]
        [Description("Show a warning message before moving tags")]
        public bool ShowTagParentChangeMessage
        {
            get { return m_showTagParentChangeMessage; }
            set { m_showTagParentChangeMessage = value; }
        }

        [Category("Warnings")]
        [DisplayName("Ask before Creating Image Version")]
        [Description("Ask the user if he would like to create a new version of the image before editing.")]
        public bool ShowImageCreateVersionMessage
        {
            get { return m_showImageCreateVersionOnEditMessage; }
            set { m_showImageCreateVersionOnEditMessage = value; }
        }

        [DisplayName("Cached image size")]
        [Browsable(false)]
        [TypeConverter(typeof(FixedListSizeConverter))]
        public Size CachedThumbnailSize
        {
            get { return m_cachedThumbnailSize; }
            set { m_cachedThumbnailSize = value; }
        }

        [DisplayName("Cache Settings")]
        [Description("Change different settings related to the thumbnails cache")]
        [EditorAttribute(typeof(UICacheSettingsEditor), typeof(UITypeEditor))]
        public Object ThumbnailCacheSettings
        {
            get { return null; }
            set { }
        }

        [DisplayName("Image cache path")]
        [Browsable(false)]
        public string ImageCachePath
        {
            get { return m_imageCachePath; }
            set { m_imageCachePath = value; }
        }

        [DisplayName("Filter selected images")]
        [Description("When set to true, using the 'Syncronize selected images' button on the selected images pane, will filter the view in addition to selecting the images")]
        public bool FilterSyncronizedSelection
        {
            get { return m_filterSyncronizedSelection; }
            set { m_filterSyncronizedSelection = value; }
        }

        [DisplayName("Update image metadata(EXIF) when changed")]
        [Description("Some applications does not change EXIF information after editing the image, you can set this option to true if you whould like My Photo Index to update the data when a change in the file is detected")]
        public bool UpdateImageMetadataOnChange
        {
            get { return m_updateImageMetadataOnChange; }
            set { m_updateImageMetadataOnChange = value; }
        }

        [DisplayName("Date Format")]
        [Description("Sets the default Date format for the application")]
        [TypeConverter(typeof(FixedListDateFormatsConverter))]
        public string DisplayDateFormat
        {
            get { return m_displayDateFormat; }
            set { m_displayDateFormat = value; }
        }

        [Browsable(false)]
        public string LastImportPath
        {
            get { return m_lastImportPath; }
            set { m_lastImportPath = value; }
        }

        [Browsable(false)]
        public string LastMoveToPath
        {
            get { return m_lastMoveToPath; }
            set { m_lastMoveToPath = value; }
        }

        [DisplayName("Proxy Settings")]
        [Description("Change Web Proxy settings")]
        [EditorAttribute(typeof(UIProxySettingsEditor), typeof(UITypeEditor))]
        public Object ProxySettings
        {
            get { return null; }
            set { }
        }

        [Browsable(false)]
        public ProxySettings WebProxySettings
        {
            get { return m_proxySettings; }
            set { m_proxySettings = value; }
        }

        [Browsable(false)]
        public RecentlyUsedIndexList RecentlyUsedIndexes
        {
            get { return m_recentlyUsedIndexes; }
            set { m_recentlyUsedIndexes = value; }
        }

        [DisplayName("Keyboard mappings")]
        [Description("Change Keyboard shortcuts")]
        [Browsable(false)]
        public KeyboardMappings KeyboardMappings
        {
            get { return m_keyboardMappings; }
            set { m_keyboardMappings = value; }
        }

        [Browsable(false)]
        public ThumbnailTextInfo ThumbnailTextInfoDisplayType
        {
            get { return m_thumbnailTextInfoDisplayType; }
            set { m_thumbnailTextInfoDisplayType = value; }
        }
    }

    class UIFileNameEditor : FileNameEditor
    {
        public UIFileNameEditor()
        {

        }

        protected override void InitializeDialog(System.Windows.Forms.OpenFileDialog openFileDialog)
        {
            base.InitializeDialog(openFileDialog);
            openFileDialog.Filter = "Image editor executable files (*.exe) | *.exe";
        }
    }

    public class FixedListDateFormatsConverter : StringConverter
    {
        public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
        {
            return true;
        }

        public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
        {
            return true;
        }

        public override TypeConverter.StandardValuesCollection
               GetStandardValues(ITypeDescriptorContext context)
        {
            Collection<string> allowedDateFormatsCollection = new Collection<string>();
            string sep = CultureInfo.CurrentUICulture.DateTimeFormat.DateSeparator;
            allowedDateFormatsCollection.Add(string.Format("M{0}d{0}yyyy", sep));
            allowedDateFormatsCollection.Add(string.Format("d{0}M{0}yyyy", sep));
            allowedDateFormatsCollection.Add(string.Format("yyyy{0}M{0}d", sep));
            allowedDateFormatsCollection.Add(string.Format("yyyy{0}d{0}M", sep));
            return new StandardValuesCollection(allowedDateFormatsCollection);
        }
    }

    public class FixedListSizeConverter : SizeConverter
    {
        public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
        {
            return true;
        }

        public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
        {
            return true;
        }

        public override System.ComponentModel.TypeConverter.StandardValuesCollection
               GetStandardValues(ITypeDescriptorContext context)
        {
            Collection<Size> allowedSizeCollection = new Collection<Size>();
            allowedSizeCollection.Add(new Size(240, 160));
            allowedSizeCollection.Add(new Size(320, 240));
            allowedSizeCollection.Add(new Size(640, 480));
            return new StandardValuesCollection(allowedSizeCollection);
        }
    }


    class UICacheSettingsEditor : UITypeEditor
    {
        public UICacheSettingsEditor()
        {

        }

        public override bool GetPaintValueSupported(ITypeDescriptorContext context)
        {
            return true;
        }

        public override void PaintValue(PaintValueEventArgs e)
        {
            e.Graphics.FillRectangle(System.Drawing.Brushes.White, e.Bounds);
        }

        public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
        {
            return UITypeEditorEditStyle.Modal;
        }

        public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
        {
            try
            {
                CacheSettingsForm csf = new CacheSettingsForm();
                csf.ShowDialog();

                return base.EditValue(context, provider, value);
            }
            catch (Exception ex)
            {
                Logger.Log(ex);
            }

            return null;
        }
    }

    class UIProxySettingsEditor : UITypeEditor
    {
        public UIProxySettingsEditor()
        {

        }

        public override bool GetPaintValueSupported(ITypeDescriptorContext context)
        {
            return true;
        }

        public override void PaintValue(PaintValueEventArgs e)
        {
            e.Graphics.FillRectangle(System.Drawing.Brushes.White, e.Bounds);
        }

        public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
        {
            return UITypeEditorEditStyle.Modal;
        }

        public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
        {
            try
            {
                ProxySettingsForm psf = new ProxySettingsForm();
                psf.ShowDialog();

                return base.EditValue(context, provider, value);
            }
            catch (Exception ex)
            {
                Logger.Log(ex);
            }

            return null;
        }
    }
}
